package com.cheifsteam.springframework.aop.aspectj;

import com.cheifsteam.springframework.aop.ClassFilter;
import com.cheifsteam.springframework.aop.MethodMatcher;
import com.cheifsteam.springframework.aop.Pointcut;
import org.aspectj.weaver.tools.PointcutExpression;
import org.aspectj.weaver.tools.PointcutParser;
import org.aspectj.weaver.tools.PointcutPrimitive;

import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

/**
 * @author qrx
 * @date 2025/8/5 9:34
 * @description: 切点表达式
 */
/**
 * AspectJ表达式切入点实现类，实现了Pointcut、ClassFilter和MethodMatcher接口
 * 用于通过AspectJ表达式匹配类和方法
 */
public class AspectJExpressionPointcut implements Pointcut, ClassFilter, MethodMatcher {

    // 支持的AspectJ原语集合（目前只支持EXECUTION）
    private static final Set<PointcutPrimitive> SUPPORTED_PRIMITIVES = new HashSet<PointcutPrimitive>();

    // 静态初始化块，添加支持的原语类型
    static {
        SUPPORTED_PRIMITIVES.add(PointcutPrimitive.EXECUTION);
    }

    // 存储解析后的切入点表达式
    private final PointcutExpression pointcutExpression;

    /**
     * 构造函数，解析AspectJ表达式
     * @param expression 切入点表达式字符串
     */
    public AspectJExpressionPointcut(String expression) {
        // 获取支持指定原语并使用指定类加载器进行解析的解析器
        PointcutParser pointcutParser = PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution(
                SUPPORTED_PRIMITIVES,
                this.getClass().getClassLoader());
        // 解析表达式并存储结果
        pointcutExpression = pointcutParser.parsePointcutExpression(expression);
    }

    /**
     * 类匹配方法，判断类是否可能包含匹配的连接点
     * @param clazz 要匹配的类
     * @return 如果类可能包含匹配的连接点则返回true
     */
    @Override
    public boolean matches(Class<?> clazz) {
        return pointcutExpression.couldMatchJoinPointsInType(clazz);
    }

    /**
     * 方法匹配方法，判断方法是否匹配切入点表达式
     * @param method 要匹配的方法
     * @param targetClass 目标类
     * @return 如果方法匹配则返回true
     */
    @Override
    public boolean matches(Method method, Class<?> targetClass) {
        return pointcutExpression.matchesMethodExecution(method).alwaysMatches();
    }

    /**
     * 获取类过滤器
     * @return 返回当前对象（实现了ClassFilter接口）
     */
    @Override
    public ClassFilter getClassFilter() {
        return this;
    }

    /**
     * 获取方法匹配器
     * @return 返回当前对象（实现了MethodMatcher接口）
     */
    @Override
    public MethodMatcher getMethodMatcher() {
        return this;
    }
}